package com.lin.realm;

import com.lin.pojo.User;
import com.lin.services.UserService;
import com.lin.utils.MD5Util;
import com.lin.utils.ShiroUtil;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Set;

/**
 * shiro认证
 */
public class MyShiroRealm extends AuthorizingRealm {

    @Autowired
    private UserService userService;

    /**
     * 授权(验证权限时调用)
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        Integer userId = ShiroUtil.getUserId();
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        User user = userService.getUserById(userId);
        if (user != null && user.getStatus() == 1) {
            //用户角色 暂未用到角儿验证 @RequiresRoles
//        Set<String> rolesSet = userService.listUserRole(userId);
            //用户权限 @RequiresPermissions
            Set<String> authoritySet = userService.listUserAuthority(userId);
            if (user.getStoreId() == null) {
                authoritySet.add("store:haveNoStore");
            } else {
                authoritySet.add("store:haveStore");
            }
//        info.setRoles(rolesSet);
            info.setStringPermissions(authoritySet);
        }
        return info;
    }

    /**
     * 认证(登录时调用)
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(
            AuthenticationToken token) throws AuthenticationException {
        String username = (String) token.getPrincipal();
//        密碼不能使用(String)token.getCredentials()强轉,因为getCredentials()底层是字符数组接收的密码
        String password = new String((char[]) token.getCredentials());
        //查询用户信息
        User user = userService.getUserByUsername(username);
        String newPassword = MD5Util.encrypted(username, password);
        //账号不存在
        if (user == null) {
            throw new UnknownAccountException();
        }
        //密码错误
        if (!newPassword.equals(user.getPwd())) {
            throw new IncorrectCredentialsException();
        }
        //账号锁定
        if (user.getStatus() == 0) {
            throw new LockedAccountException("账号数据异常，请联系管理员");
        }
        return new SimpleAuthenticationInfo(user, user.getPwd(), ByteSource.Util.bytes(username + MD5Util.SALT), this.getName());
    }

}
